package cn.tedu.reflection;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

/*
Author     :Dsi
Date       : 2021/11/23 16:12
Description: 该类用于测试暴力反射
*/
public class TestReflact02 {
    /*测试1.通过暴力反射技术，获取私有属性并且操作私有属性*/
    @Test
    public void getField2() throws Exception {
        /*1.获取属性值*/
        //1.获取字节码对象
        Class<?> c = Person.class;
        //2.通过字节码对象获取指定的私有属性
        Field f = c.getDeclaredField("name");

        System.out.println(f);
        System.out.println(f.getType());//获取对象
        System.out.println(f.getType().getName());//通过获取的对象获取名字
        /*2.设置属性值*/
        //思路：给哪个对象设置属性值，给对象的哪个属性赋值，赋什么值
        //1.利用反射获取目标对象

        Object p = c.newInstance();
        f.setAccessible(true);
        //2.利用反射给刚刚获取的对象设置属性值
        //set（m,n）m--是给谁赋值，n--是赋什么值
        f.set(p,"45");
        //fiel.get（m）--field表示的就是name属性，m--目标对象
        System.out.println(f.get(p));

    }
    @Test
    public void getField3() throws Exception {
        Class<?> c=Person.class;

        Field f = c.getDeclaredField("age");
        f.setAccessible(true);

        Constructor<?> a = c.getDeclaredConstructor();
        a.setAccessible(true);

        Object oo = a.newInstance();
        f.set(oo,45);
        System.out.println(f.get(oo));

    }
    /*测试2:通过暴力测试获取并执行私有方法*/
    @Test
    public void getFunction() throws Exception {
        Class<?> c = Person.class;//获取字节码

        Method m = c.getDeclaredMethod("save", int.class, String.class);//通过字节码获取方法对
        m.setAccessible(true);

        Constructor<?> declaredConstructor = c.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);


        Object o = declaredConstructor.newInstance();

        /*invoke（o，x，y，z...），表示通过反射技术给对应的对象执行指定的方法
        * o是指对应的方法
        * x，y,z...：执行对应方法时需要传入的参数*/
        m.invoke(o,45,"45");
        System.out.println(m);
    }
}

























